local all = require "prefabs/rg_weapons_all".all

local fn = nil
local TEMPLATE = {
	rarity = 1,						-- auto
	name = "spear", 				-- auto
	prefab = "rg_spear", 			-- auto
	tags   = {"sharp"},
	dlc    = "HAM",					-- dlc require ROG/SW/HAM

	build  = "rg_spear",			
	bank   = "rg_spear",			
	anim   = "idle",				
	anim_float = "idle_water",		

	sound = true, 					

	build_onhand = "rg_swap_spear", -- string
	symbol       = "swap_spear",	-- string/array
	symbol 		 = {
		{"swap_object", "swap_spear"},
		{"symbol2",		"symbol2"},
	},

	damage 	= 34,

	attackstate = "chop",

	components = { "inspectable"},
	init = { 
		weapon = {    -- lower case
			SetDamage = {34},
		},
		OnLoad = fn,  -- contains upper case -> inst.OnLoad
		["inst.energy"] = 0,   -- explicit   -> inst.energy
	},
	postinit = fn,    -- function(inst) ... end
	data = {},

	assets = {},
}

local prefabs = {}

local function MakeWeapon(data)
	print("[RG] MakeWeapon: ".. data.prefab)

	local assets = {
		Asset("ANIM", "anim/"..data.build..".zip"),
		Asset("ANIM", "anim/"..data.build_onhand..".zip"),
	}
	for _,v in ipairs(data.assets or {})do
		table.insert(assets, v)
	end

	--- safe filter
	for i = #assets, 1, -1 do
		if softresolvefilepath(assets[i].file) == nil then
			print("RG: Safe asset skip: ", assets[i].file)
			table.remove(assets, i)
		end
	end

	local function onequip(inst, owner)
		for _,v in ipairs(data.symbol)do
			owner.AnimState:OverrideSymbol(v[1], data.build_onhand, v[2])
		end
	    -- owner.AnimState:OverrideSymbol("swap_object", "swap_spear", "swap_spear")
	    owner.AnimState:Show("ARM_carry") 
	    owner.AnimState:Hide("ARM_normal") 
	end

	local function onunequip(inst, owner) 
	    owner.AnimState:Hide("ARM_carry") 
	    owner.AnimState:Show("ARM_normal") 
	end	

	local function fn()
		local inst = CreateEntity()
		local trans = inst.entity:AddTransform()
		local anim = inst.entity:AddAnimState()
		if data.sound then
			inst.entity:AddSoundEmitter()
		end
		MakeInventoryPhysics(inst)

		anim:SetBank(data.bank)
		anim:SetBuild(data.build)
		if rawget(_G, "MakeInventoryFloatable") then
			MakeInventoryFloatable(inst, data.anim_float, data.anim)
		end

		for _,v in ipairs(data.tags)do
			inst:AddTag(v)
		end

		inst:AddComponent("inspectable")

		inst:AddComponent("weapon")
		inst.components.weapon:SetDamage(data.damage)
		if data.projectile ~= nil then
			inst.projectile = data.projectile
			inst.components.weapon:SetProjectile(data.projectile)
		end

		inst:AddComponent("inventoryitem")
		-- setter

		inst:AddComponent("equippable")
		inst.components.equippable:SetOnEquip(onequip)
	    inst.components.equippable:SetOnUnequip(onunequip)

	    inst:AddComponent("rg_dlccheck")
	    inst.components.rg_dlccheck:SetDLC(data.dlc)

	    for _,v in ipairs(data.components or {})do
	    	if softresolvefilepath("components/"..v) == nil then
	    		error("Cannot load component: "..v)
	    	else
	    		inst:AddComponent(v)
	    	end
	    end

	    for k,v in pairs(data.init or {})do
	    	local this = inst
	    	if k:sub(1,5) == "inst." then
	    		k = k:sub(6)
	    	elseif k:lower() == k then
	    		if inst.components[k] == nil then
	    			inst:AddComponent(k)
	    		end
	    		this = inst.components[k]
	    		-- assert(this ~= nil, "inst.components."..k.." is nil.")
	    	else
	    		assert(this[k] == nil, "Value '"..k.."' is overrided.")
	    	end

	    	if inst == this then
	    		inst[k] = v
	    	else
	    		for method, param in pairs(v)do
	    			-- print("\tCall "..k..":"..method.."()")
	    			this[method](this, unpack(param))
	    		end
	    	end
	    end

	    inst.attackstate = data.attackstate

	    if data.postinit ~= nil then
	    	data.postinit(inst)
	    end

		return inst
	end

	return Prefab(data.prefab, fn, assets)
end

table.foreach(all, function(k,v) MakeWeapon(v) end)

return unpack(prefabs)